﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
using PMIS.BLL;
using PMIS.BLL.Department;

namespace PMIS.UI.Department
{
	/// <summary>
	/// 部门班组信息维护
	/// </summary>
	public partial class 部门班组信息维护 : BaseDockForm
	{
		#region 私有变量
		/// <summary>
		/// 标识当前的记录是否是只读的
		/// </summary>
		private bool bIsCurrentRecordReadonly = true;
		/// <summary>
		/// 部门信息列表
		/// </summary>
		private List<部门> listDepartment = null;
		/// <summary>
		/// 当前操作的记录
		/// </summary>
		private 部门 CurrentRecord = null;
		#endregion

		#region 单例
		/// <summary>
		/// 本类的实例
		/// </summary>
		private static 部门班组信息维护 _form = null;
		/// <summary>
		/// 用于本类实现单例的Locker
		/// </summary>
		private static object locker = new object();
		/// <summary>
		/// 构造函数
		/// </summary>
		private 部门班组信息维护()
		{
			InitializeComponent();
		}
		/// <summary>
		/// 获取本窗体的实例
		/// </summary>
		/// <returns></returns>
		public static 部门班组信息维护 GetInstance()
		{
			if (_form == null || _form.IsDisposed)
			{
				lock (locker)
				{
					if (_form == null || _form.IsDisposed)
						_form = new 部门班组信息维护();
				}
			}

			return _form;
		}
		#endregion

		#region 窗体事件
		/// <summary>
		/// 窗体载入事件
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void 部门班组信息维护_Load(object sender, EventArgs e)
		{
			bIsCurrentRecordReadonly = true;
			//	注册事件
			部门班组选择.SelectionChanged += new EventHandler<NotifyEventArgs<部门>>(部门班组选择_SelectionChanged);
			//	刷新界面
			tsbtRefresh_Click(null, null);
		}
		/// <summary>
		/// 窗体关闭事件
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void 部门班组信息维护_FormClosed(object sender, FormClosedEventArgs e)
		{
			//	注销事件
			部门班组选择.SelectionChanged -= new EventHandler<NotifyEventArgs<部门>>(部门班组选择_SelectionChanged);
		}
		#endregion

		#region 界面显示
		/// <summary>
		/// 更新界面显示
		/// </summary>
		private void UpdateFormView()
		{
			try
			{
				if (this.InvokeRequired)
				{
					this.Invoke(new Action(UpdateFormView));
				}
				else
				{
					cb类型.Enabled = !bIsCurrentRecordReadonly;
					bt设为顶级.Enabled = !bIsCurrentRecordReadonly;
					tb名称.ReadOnly = bIsCurrentRecordReadonly;
					tb备注.ReadOnly = bIsCurrentRecordReadonly;

					if (CurrentRecord == null || listDepartment == null)
						return;

					//	类型
					cb类型.Text = CurrentRecord.类型;
					//	上级部门
					if (CurrentRecord.上级部门ID == "0")
					{
						tb上级部门.Text = "(顶级部门)";
						tb上级部门.Tag = "0";
					}
					else
					{
						部门 pd = listDepartment.Find(t => t.ID == CurrentRecord.上级部门ID);
						if (pd == null)
							throw new Exception("查找部门班组信息时发生错误!");

						tb上级部门.Text = pd.名称;
						tb上级部门.Tag = pd.ID;
					}
					//	名称
					tb名称.Text = CurrentRecord.名称;
					//	备注
					tb备注.Text = CurrentRecord.备注;
				}
			}
			catch (Exception ex)
			{
				ShowExceptionMessage(ex);
			}
		}
		/// <summary>
		/// 更新界面显示
		/// </summary>
		private void UpdateTreeView()
		{
			try
			{
				if (tvDepartment.InvokeRequired)
				{
					tvDepartment.Invoke(new Action(UpdateTreeView));
				}
				else
				{
					//	获取所有部门班组信息
					listDepartment = Singleton<BL_部门>.GetInstance().GetAll();
					if (listDepartment == null)
						throw new Exception("获取部门信息时发生错误!");

					tvDepartment.BeginUpdate();
					tvDepartment.Nodes.Clear();
					//	递推一次性建树
					UpdateTreeNodesByParent(null);
					tvDepartment.EndUpdate();
				}
			}
			catch (Exception ex)
			{
				ShowExceptionMessage(ex);
			}
		}
		/// <summary>
		/// 根据父节点来递推建树
		/// </summary>
		/// <param name="tnParent">父节点</param>
		private void UpdateTreeNodesByParent(TreeNode tnParent)
		{
			if (listDepartment == null)
				return;

			List<部门> list = tnParent == null ?
				listDepartment.FindAll(t => t.上级部门ID == "0") :
				listDepartment.FindAll(t => t.上级部门ID == (tnParent.Tag as 部门).ID);
			if (list == null)
				return;

			#region 增加部门节点
			List<部门> departments = list.FindAll(t => t.类型 == "部门");
			departments.Sort((x, y) => x.名称.CompareTo(y.名称));
			foreach (部门 department in departments)
			{
				TreeNode node = new TreeNode();
				node.Text = department.名称;
				node.Tag = department;
				node.SelectedImageIndex = node.ImageIndex = 0;

				//	递推建树
				UpdateTreeNodesByParent(node);

				if (tnParent == null)
				{
					tvDepartment.Nodes.Add(node);
					node.Expand();
				}
				else
				{
					tnParent.Nodes.Add(node);
				}
			}
			#endregion

			#region 增加班组节点
			List<部门> teams = list.FindAll(t => t.类型 == "班组");
			teams.Sort((x, y) => x.名称.CompareTo(y.名称));
			foreach (部门 team in teams)
			{
				TreeNode node = new TreeNode();
				node.Text = team.名称;
				node.Tag = team;
				node.SelectedImageIndex = node.ImageIndex = 1;

				if (tnParent == null)
				{
					tvDepartment.Nodes.Add(node);
				}
				else
				{
					tnParent.Nodes.Add(node);
				}
			}
			#endregion
		}
		/// <summary>
		/// 查找并更新节点状态
		/// </summary>
		/// <param name="tnParent"></param>
		/// <param name="name"></param>
		public void UpdateTreeNodeStateByDepartmentAndTeamName(TreeNode tnParent, string name)
		{
			if (string.IsNullOrEmpty(name))
				return;

			TreeNodeCollection tnc = tnParent == null ? tvDepartment.Nodes : tnParent.Nodes;
			bool fit = false, contains = false;
			foreach (TreeNode node in tnc)
			{
				fit = false;
				//	收起节点
				node.Collapse();

				//	按名称查询
				fit = node.Text.Contains(name);

				//	递推查找
				UpdateTreeNodeStateByDepartmentAndTeamName(node, name);

				//	符合查询条件则节点文本颜色变为醒目的红色,不符合查询条件的节点文本颜色变为原来的黑色
				node.ForeColor = fit ? Color.Red : Color.Black;
				//	是否需要逐级展开父节点
				contains = contains | fit;
			}

			if (contains)
			{
				//	逐级展开父节点
				TreeNode pn = tnParent;
				while (pn != null)
				{
					pn.Expand();
					pn = pn.Parent;
				}
			}
		}
		#endregion

		#region 触发事件
		/// <summary>
		/// 树节点选择事件
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void tvDepartment_AfterSelect(object sender, TreeViewEventArgs e)
		{
			try
			{
				CurrentRecord = e.Node.Tag as 部门;
				bIsCurrentRecordReadonly = true;
				//	更新界面显示
				UpdateFormView();
			}
			catch (Exception ex)
			{
				ShowExceptionMessage(ex);
			}
		}
		/// <summary>
		/// 点击了上级部门
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void tb上级部门_Click(object sender, EventArgs e)
		{
			if (bIsCurrentRecordReadonly)
				return;

			try
			{
				部门班组选择 form = 部门班组选择.GetInstance();
				if (form == null)
					throw new Exception("无法获取部门班组选择窗体");

				form.ShowDialog(this);
			}
			catch (Exception ex)
			{
				ShowExceptionMessage(ex);
			}
		}
		/// <summary>
		/// 选择部门班组
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void 部门班组选择_SelectionChanged(object sender, NotifyEventArgs<部门> e)
		{
			try
			{
				if (e.value.类型 == "班组")
				{
					ShowErrorMessage("班组不能再增加下级机构!");
					return;
				}
				else
				{
					tb上级部门.Text = e.value.名称;
					tb上级部门.Tag = e.value.ID;
				}
			}
			catch (Exception ex)
			{
				ShowExceptionMessage(ex);
			}
		}
		/// <summary>
		/// 设为顶级部门
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void bt设为顶级_Click(object sender, EventArgs e)
		{
			tb上级部门.Text = "(顶级部门)";
			tb上级部门.Tag = "0";
		}
		/// <summary>
		/// 查询
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void tsbtQuery_Click(object sender, EventArgs e)
		{
			if (string.IsNullOrEmpty(tstb名称.Text.Trim()))
			{
				ShowMessageBox("请输入要查询的部门或班组名称!");
				return;
			}

			try
			{
				tvDepartment.BeginUpdate();
				//	查找并显示
				UpdateTreeNodeStateByDepartmentAndTeamName(null, tstb名称.Text.Trim());
				tvDepartment.EndUpdate();
			}
			catch (Exception ex)
			{
				ShowExceptionMessage(ex);
			}
		}
		/// <summary>
		/// 清空
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void tsbtReset_Click(object sender, EventArgs e)
		{
			tstb名称.Text = string.Empty;
		}
		/// <summary>
		/// 增加
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void tsbtAdd_Click(object sender, EventArgs e)
		{
			try
			{
				CurrentRecord = new 部门();
				if (tvDepartment.SelectedNode != null)
				{
					if (tvDepartment.SelectedNode.ImageIndex == 1)
					{
						ShowErrorMessage("班组不能再增加下级机构!");
						return;
					}

					CurrentRecord.上级部门ID = (tvDepartment.SelectedNode.Tag as 部门).ID;
				}
				else
				{
					CurrentRecord.上级部门ID = "0";
				}
				bIsCurrentRecordReadonly = false;
				//	更新部门信息
				UpdateFormView();
			}
			catch (Exception ex)
			{
				ShowExceptionMessage(ex);
			}
		}
		/// <summary>
		/// 修改
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void tsbtModify_Click(object sender, EventArgs e)
		{
			if (tvDepartment.SelectedNode == null)
			{
				ShowMessageBox("请选择要修改的部门或班组!");
				return;
			}

			try
			{
				bIsCurrentRecordReadonly = false;
				//	更新部门信息
				UpdateFormView();
			}
			catch (Exception ex)
			{
				ShowExceptionMessage(ex);
			}
		}
		/// <summary>
		/// 删除
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void tsbtDelete_Click(object sender, EventArgs e)
		{
			if (tvDepartment.SelectedNode == null)
			{
				ShowMessageBox("请选择要删除的部门或班组!");
				return;
			}

			if (tvDepartment.SelectedNode.Nodes.Count > 0)
			{
				ShowMessageBox("请先删除下级部门或班组,然后再删除当前选择的部门或班组!");
				return;
			}

			if (ShowYesNoMessage("删除所选部门或班组?") != DialogResult.Yes)
				return;

			try
			{
				string message = string.Empty;
				if (Singleton<BL_部门>.GetInstance().Delete((tvDepartment.SelectedNode.Tag as 部门).ID, ref message))
				{
					ShowSuccessMessage("删除成功!");
					CurrentRecord = null;
					bIsCurrentRecordReadonly = true;
					tsbtRefresh_Click(null, null);
				}
				else
				{
					ShowErrorMessage(message);
				}
			}
			catch (Exception ex)
			{
				ShowExceptionMessage(ex);
			}
		}
		/// <summary>
		/// 检查用户输入
		/// </summary>
		/// <returns></returns>
		private bool CheckInput()
		{
			if (bIsCurrentRecordReadonly)
			{
				ShowErrorMessage("请修改后再保存!");
				return false;
			}

			if (cb类型.SelectedIndex < 0)
			{
				ShowErrorMessage("请选择部门类型!");
				cb类型.Focus();
				return false;
			}

			if (string.IsNullOrEmpty(tb上级部门.Tag as string))
			{
				ShowErrorMessage("请选择上级部门!");
				tb上级部门.Focus();
				return false;
			}

			if (string.IsNullOrEmpty(tb名称.Text.Trim()))
			{
				ShowErrorMessage("请输入部门或班组名称!");
				tb名称.Focus();
				return false;
			}

			return true;
		}
		/// <summary>
		/// 保存
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void tsbtSave_Click(object sender, EventArgs e)
		{
			if (!CheckInput())
				return;

			if (CurrentRecord == null)
				return;

			try
			{
				//	部门类型
				CurrentRecord.类型 = cb类型.Text;
				//	上级部门ID
				CurrentRecord.上级部门ID = tb上级部门.Tag as string;
				//	名称
				CurrentRecord.名称 = tb名称.Text.Trim();
				//	备注
				CurrentRecord.备注 = tb备注.Text.Trim();

				if (Singleton<BL_部门>.GetInstance().Save(CurrentRecord))
				{
					ShowSuccessMessage("保存成功!");
					bIsCurrentRecordReadonly = true;
					tsbtRefresh_Click(null, null);
				}
				else
				{
					ShowErrorMessage("保存部门或班组时发生错误!");
				}
			}
			catch (Exception ex)
			{
				ShowExceptionMessage(ex);
			}
		}
		/// <summary>
		/// 刷新
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void tsbtRefresh_Click(object sender, EventArgs e)
		{
			//	刷新部门班组树
			new Thread(new ThreadStart(UpdateTreeView)).Start();
			//	刷新部门信息
			new Thread(new ThreadStart(UpdateFormView)).Start();
		}
		/// <summary>
		/// 退出
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void tsbtExit_Click(object sender, EventArgs e)
		{
			this.Close();
		}
		#endregion
	}
}